<?php

include_once "function_xml_basic.php";
include_once "function_xml_atom.php";

$root_path = "/MINI/SECURITY/POLICY/BINDWIDTHS";

function GetXmlSecBindWidthByName($name)
{
	$ret_array = GetXmlSecBindWidthList();
    
        foreach ($ret_array as $ret)
        {   
                if ($ret['Name'] == $name)
                        return $ret;
        }   
        return NULL;
}

function GetXmlSecBindWidthByNumber($n)
{
	global $root_path;
	$query_string = $root_path. "/BINDWIND"."[". $n. "]";
	$key_array = array("Name", "Filter", "Dev", "Width", "Enabled", "Type");
	$list = GetAttributList($query_string, $key_array);
	$r = $list[0];
	return $r;

}
function GetXmlSecBindWidthList()
{
	global $root_path;
	$query_string = $root_path. "/BINDWIND";
	$key_array = array("Name", "Filter", "Dev", "BandWidth", "Type", "Enabled");
	return GetAttributList($query_string, $key_array);
}

function GetXmlNumberBindWidths()
{
	global $root_path;
	$query_string = $root_path. "/BINDWIND";
	return GetNumberOfNode($query_string);
}

function DelXmlSpecialOneSecBindWidth($name)
{
	global $root_path;

	$query_string = $root_path. "/BINDWIND[@Name='". $name. "']";
	DelSpecialNode($query_string);
	ApplySecBandWidthRule();
}

function AppendXmlSecOneBindWidth($in_array)
{
	global $root_path;
        $node_name = "BINDWIND";
	$query_string = $root_path;
	$in_array['Type'] = "1";
	AppendAllAttrOfNode($query_string, $node_name, $in_array);
	ApplySecBandWidthRule();
}

function InsertXmlSecOneBindWidth($number, $in_array)
{
	global $root_path;
	$node_name = "BINDWIND";
	$query_string_from = $root_path. '/BINDWIND['. $number. ']';
	InsertOneNode($query_string_from, $node_name, $in_array);
	ApplySecBandWidthRule();
}

function SetXmlSecOneBindWidth($in_array, $number)
{
	global $root_path;
	$in_array['Type'] = "1";
	$query_string = $root_path. "/BINDWIND[". $number. "]";
	EditAllAttrOfNode($query_string, $in_array);
	ApplySecBandWidthRule();
}
function GetXmlNumberSecBindWidths()
{
        global $root_path;
        $query_string = $root_path. "/BINDWIND";
	//print $query_string;
        return GetNumberOfNode($query_string);
}

function MoveXmlOneSecBindWidth($from, $to)
{
	global $root_path;
	$query_string_from = $root_path.  "/BINDWIND". "[". $from. "]";
	$query_string_to= $root_path. "/BINDWIND". "[". $to. "]";
	$query_string_number= $root_path. "/BINDWIND";
	
	if ($from == $to)
		return SUCCESS;

	$number = GetXmlNumberSecBindWidths();
	if ($from > $number || $to > $number)
	{
		//print "From:". $from;
		//print "To:". $to;
		//print "Total:". $number;
		return ERR_VALUE;
	}
	if ($from > $to)
	{
		MoveFrontOneNode($query_string_from, $query_string_to);
	}
	else
	{
		$number = GetXmlNumberSecBindWidths();
		if ($to < $number)
		{
			$query_string_to= $root_path. "/BINDWIND". "[". ($to + 1 ). "]";
			MoveFrontOneNode($query_string_from, $query_string_to);
		}
		else
		{
			MoveEndOneNode($query_string_from, $query_string_to);
		}
	}
	return SUCCESS;
	ApplySecBandWidthRule();
}

function DelXmlAllSecBindWidth()
{
	global $root_path;
	$query_string = $root_path. "/BINDWIND";
	DelSpecialNode($query_string);
	ApplySecBandWidthRule();
}

function GetSysNetDevMaxSpeedByName($dev)
{
	include_once "function_net_tools.php";
	$s = GetNetDevSpeed($dev);
	
	if ($s == NULL)
		$r = "10Mbit";
	else
	{
		$r = str_replace("Mb/s","Mbit",$s);
	}
	return $r;
}

function ApplySecBandWidthRule()
{
	$tc_command = "/usr/sbin/tc ";
	$handle_root = 1;
	$handle_root_slave = 1;

	$bandwidth_list = GetXmlSecBindWidthList();

	$dev_list = array();
	$del_root = "";
	foreach ($bandwidth_list as $bandwidth)
	{
		if ($bandwidth['Name'] == "")
			continue;
		
		if (!in_array($bandwidth['Dev'], $dev_list))
			$dev_list[] = $bandwidth['Dev'];
	}

	include_once "function_net_tools.php";
	$dev_real_list = GetNetDevList();
	foreach($dev_real_list as $di)
	{
		$del_root .= $tc_command. " qdisc del dev ". $di. " root ;";
	}

	$command = "";
	$command .= $del_root;
	foreach ($dev_list as $d)
	{
		$Max_Speed = GetSysNetDevMaxSpeedByName($d);
		
		// create qdisc
		$command .= $tc_command. " qdisc add dev ". $d. " root handle ". $handle_root. ": htb default 320 ;" ;
		// create root class
		$command .= $tc_command. " class add dev ". $d. " parent ". $handle_root. 
			    ": classid ". $handle_root. ":". $handle_root_slave. 
			    " htb rate ". $Max_Speed. " ceil ". $Max_Speed. ";";
		
		$command1 = "";
		$handle_root_slave_tmp = 10;
		foreach ($bandwidth_list as $bandwidth)
		{
			if ($bandwidth['Name'] == "" || $bandwidth['Dev'] != $d || $bandwidth['Enabled'] == 0)
				continue;

			include_once "function_obj_bindwidth.php";
			//print $bandwidth['Filter']. "\n";
        		$filter = GetXmlFilterObjectByName($bandwidth['Filter']);
        		$filter_type = $filter['Filter'];
			$value1 = $filter['Value1'];
			$value2 = $filter['Value2'];
			
			if ($filter_type == 1) // source addr
			{
				$filter_string = " u32 match ip src ". $value1. " ";
			}
			if ($filter_type == 2) // source port
			{
				$filter_string = " u32 match ip sport ". $value1. " 0xffff ";
			
			}
			if ($filter_type == 3) // dst addr
			{
				$filter_string = " u32 match ip dst ". $value1. " ";
			
			}
			if ($filter_type == 5) // dst port
			{
				$filter_string = " u32 match ip dport ". $value1. " 0xffff ";
			}
			if ($filter_type == 18) // fw mark
			{
				$filter_string = " handle ". $value1. " fw ";
			}

			//print $bandwidth['BandWidth']. "\n";
			$width = GetXmlBindObjectByName($bandwidth["BandWidth"]);
			$need_speed = $width["NeedWidth"];
			$max_speed = $width["MaxWidth"];
			$prio = $width["Proi"];
			
			// create child class and special prio.
			$command1 .= $tc_command. " class add dev ". $d. " parent ". $handle_root. ":". $handle_root_slave.
				     " classid ". $handle_root. ":". $handle_root_slave_tmp. 
				     " htb  rate ". $need_speed. "Mbit ceil ". $max_speed. "Mbit prio ". $prio. " ;";
			// match 
			$command1 .= $tc_command. " filter add dev ". $d. " protocol ip parent ".
				     $handle_root. ": prio 1 ".
				     $filter_string. " flowid ". $handle_root. ":". $handle_root_slave_tmp. " ; ";

			$handle_root_slave_tmp ++  ;
			
		}
		$command .= $command1;
	}
	//print $command;
	$ret = shell_exec($command);
}
//ApplySecBandWidthRule();

?>
